package com.docker.core.plugin;

import com.jfinal.log.Log;
import com.jfinal.plugin.IPlugin;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;

import java.util.Date;
import java.util.Map;

public class QuartzPlugin implements IPlugin {

    private static final Log log = Log.getLog(QuartzPlugin.class);

    private static Scheduler scheduler = null;

    private static long delayTimes = 5000; // 延迟xx毫秒执行，0表示不延迟

    /**
     * 添加调度任务
     *
     * @param triggerName 全局唯一调度任务ID
     * @param cron        调度任务表达式
     * @param classs      调度处理类
     */
    public static void addJob(String triggerName, String cron, Class<? extends Job> classs) {
        addJob(triggerName, cron, classs, null);
    }

    /**
     * 添加调度任务
     *
     * @param triggerName 全局唯一调度任务ID
     * @param cron        调度任务表达式
     * @param classs      调度处理类
     * @param param       调度任务参数
     */
    public static void addJob(String triggerName, String cron, Class<? extends Job> classs, Map<String, String> param) {
        ScheduleBuilder<CronTrigger> schedBuilder = CronScheduleBuilder.cronSchedule(cron);
        addJob(triggerName, schedBuilder, classs, param);
    }

    /**
     * 添加调度任务
     *
     * @param triggerName  全局唯一调度任务ID
     * @param schedBuilder 调度任务表达式
     * @param classs       调度处理类
     * @param param        调度任务参数
     *                     <p>
     *                     ScheduleBuilder常见调度类型
     *                     1.CronScheduleBuilder.cronSchedule(cron) // 轮询时间，表达式
     *                     2.SimpleScheduleBuilder.repeatHourlyForever(24) // 轮询时间，24小时
     *                     3.SimpleScheduleBuilder.repeatMinutelyForever(60) // 轮询时间，60分钟
     *                     4.SimpleScheduleBuilder.repeatSecondlyForever(60) // 轮询时间，60秒
     *                     5.SimpleScheduleBuilder.simpleSchedule()
     *                     .withIntervalInSeconds(10) //时间间隔
     *                     .withRepeatCount(5)        //重复次数(将执行6次)
     */
    public static void addJob(String triggerName, ScheduleBuilder<CronTrigger> schedBuilder, Class<? extends Job> classs, Map<String, String> param) {
        try {
            boolean exists = scheduler.checkExists(TriggerKey.triggerKey(triggerName, Scheduler.DEFAULT_GROUP));
            if (exists) {
                if (log.isWarnEnabled()) log.warn("调度任务已经存在triggerKey = " + triggerName);
                throw new RuntimeException("调度任务已存在");
            }

            JobDetail jobDetail = JobBuilder.newJob(classs).withIdentity(triggerName, Scheduler.DEFAULT_GROUP).build();

            if (param != null && !param.isEmpty()) {
                jobDetail.getJobDataMap().putAll(param);
            }

            Trigger trigger = TriggerBuilder.newTrigger().withIdentity(triggerName, Scheduler.DEFAULT_GROUP)
                    .withSchedule(schedBuilder)
                    .startAt(new Date(System.currentTimeMillis() + delayTimes))
                    .build();

            scheduler.scheduleJob(jobDetail, trigger);
        } catch (SchedulerException e) {
            e.printStackTrace();
            throw new RuntimeException(e.getMessage());
        }
    }

    /**
     * 删除调度任务
     *
     * @param triggerName
     */
    public static boolean deleteJob(String triggerName) {
        try {
            scheduler.pauseTrigger(TriggerKey.triggerKey(triggerName, Scheduler.DEFAULT_GROUP));
            scheduler.deleteJob(JobKey.jobKey(triggerName, Scheduler.DEFAULT_GROUP));
            scheduler.unscheduleJob(TriggerKey.triggerKey(triggerName, Scheduler.DEFAULT_GROUP));
            return true;
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
        return false;
    }

    @Override
    public boolean start() {
        if (scheduler == null) {
            try {
                // 加载配置文件
                //StdSchedulerFactory factory = new StdSchedulerFactory("quartz.properties");
                StdSchedulerFactory factory = new StdSchedulerFactory();
                factory.initialize();

                scheduler = factory.getScheduler();
                scheduler.start();
            } catch (SchedulerException e) {
                if (log.isErrorEnabled()) log.error("初始化任务调度出错", e);
            }
        }
        return true;
    }

    @Override
    public boolean stop() {
        try {
            if (scheduler != null && !scheduler.isShutdown()) {
                scheduler.shutdown();
            }
        } catch (SchedulerException e) {
            if (log.isErrorEnabled()) log.error("关闭任务调度出错", e);
        }
        return true;
    }
}
